package com.expert.service.impl;

import com.expert.common.page.MyPage;
import com.expert.common.utils.FormUtils;
import com.expert.entity.Feature;
import com.expert.entity.Result;
import com.expert.entity.Rule;
import com.expert.mapper.RuleMapper;
import com.expert.service.FeatureService;
import com.expert.service.ResultService;
import com.expert.service.RuleService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Mankind
 * @since 2018-06-03
 */
@Service
public class RuleServiceImpl extends ServiceImpl<RuleMapper, Rule> implements RuleService {

    @Autowired
    private FeatureService featureService;
    @Autowired
    private ResultService resultService;
    public MyPage<Rule> list(MyPage<Rule> page) {
        List<Rule> rules = baseMapper.list(page);
        for(Rule rule:rules){
            String condition="";
            String result="";
            if(StringUtils.isNotEmpty(rule.getFacts())){
                List<Long> ids= Arrays.asList(FormUtils.getIdsArray(rule.getFacts()));
                List<Feature> featureList=featureService.selectBatchIds(ids);
                int flag=0;
                for(Feature feature:featureList){
                    if(flag==0){
                        condition+=feature.getName();
                        flag=1;
                    }else{
                        condition+=","+feature.getName();
                    }
                }
            }
            if(rule.getEndResult()!=null&&rule.getResultId()!=null){
                if(rule.getEndResult()==true){
                    result=resultService.selectById(rule.getResultId()).getName();
                }else if(rule.getEndResult()==false){
                    result=featureService.selectById(rule.getResultId()).getName();
                }
            }
            rule.setCondition(condition);
            rule.setResult(result);
        }
        page.setRecords(rules);
        return page;
    }

    public Result forecast(String facts) {
        Long[] temp=FormUtils.getIdsArray(facts);
        List<Long> ids=new ArrayList<Long>();
        for(int i=0;i<temp.length;i++){
            ids.add(temp[i]);
        }
        int n=ids.size();
//        List<Feature> featureList=featureService.selectBatchIds(ids);
        boolean isEnd = false;
        boolean findAns = false;
        List<Rule> rules=this.selectList(null);
        for(Rule rule:rules){
            rule.setNextFactPos(0);
            rule.setUsed(false);
            rule.setPossible(true);
        }
        while(!isEnd){
            isEnd= true;
            for(int i=0;i<rules.size();i++){
                if(rules.get(i).isUsed() || !rules.get(i).isPossible()) continue;//该规则失效
                int res = cmp(rules.get(i),ids);
                if(res == 0){
                    continue;//不匹配
                }else if(res == 1){
                    //匹配，但是为中间值,添加该中间值到ids列表中
                    ids.add(rules.get(i).getResultId());
                    isEnd= false;
                    break;
                }else if(res == 2){
                    //匹配，且为最终答案
                    Result result=resultService.selectById(rules.get(i).getResultId());
                    return result;
                }
            }
        }
        return null;
    }

    private int cmp(Rule r,List<Long> ids){
        List<Long> F_Rule = Arrays.asList(FormUtils.getIdsArray(r.getFacts()));
        int factNum =ids.size();

        for(int i=r.getNextFactPos();i<F_Rule.size();i++){
            boolean isMatch=false;
            for(int j=0;j<factNum;j++){
                if(F_Rule.get(i) == ids.get(j)){//匹配成功
                    if(i+1 == F_Rule.size()){//全部规则特征已匹配完毕
                        r.setUsed(true);
                        if(r.getEndResult()){
                            //是最终答案
                            return 2;
                        }else{
                            //中间特征
                            return 1;
                        }
                    }
                    //部分特征匹配成功，开始匹配下一个特征
                    isMatch=true;
                    break;
                }else{
                    //不匹配，继续循环
                    continue;
                }
            }
            if(isMatch){
                //匹配成功
                continue;
            }else{
                //匹配失败
                r.setNextFactPos(i);
                return 0;
            }
        }
        //无匹配项
        return 0;
    }
}
